package com.fancy.playlist.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fancy.common.dto.PageResult;
import com.fancy.common.dto.PlaylistBasicInfo;
import com.fancy.common.dto.SongBasicInfo;
import com.fancy.common.dto.response.Result;
import com.fancy.imasclient.client.MusicServiceClient;
import com.fancy.imasclient.client.UserServiceClient;
import com.fancy.imasclient.dto.UserBasicInfo;
import com.fancy.playlist.dto.PlaylistDetailDTO;
import com.fancy.playlist.entity.Playlist;
import com.fancy.playlist.entity.PlaylistSong;
import com.fancy.playlist.mapper.PlaylistMapper;
import com.fancy.playlist.mapper.PlaylistSongMapper;
import com.fancy.playlist.service.PlaylistService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PlaylistServiceImpl implements PlaylistService {

    private final PlaylistMapper playlistMapper;
    private final PlaylistSongMapper playlistSongMapper;
    private final MusicServiceClient musicServiceClient;
    private final UserServiceClient userServiceClient;

    @Override
    @Transactional
    public Long createPlaylist(Long userId, String playlistName, String description, String coverUrl, Boolean isPublic) {
        try {
            Playlist playlist = new Playlist();
            playlist.setUserId(userId);
            playlist.setPlaylistName(playlistName);
            playlist.setDescription(description);
            playlist.setCoverUrl(coverUrl);
            playlist.setIsPublic(isPublic != null ? isPublic : true);
            playlist.setSongCount(0);
            playlist.setPlayCount(0L);
            playlist.setCollectCount(0L);
            playlist.setShareCount(0L);
            playlist.setCreateTime(new Date());
            playlist.setUpdateTime(new Date());

            playlistMapper.insert(playlist);
            return playlist.getPlaylistId();
        } catch (Exception e) {
            log.error("创建播放列表失败", e);
            return null;
        }
    }

    @Override
    public Playlist getPlaylistDetail(Long playlistId) {
        return playlistMapper.selectById(playlistId);
    }

    @Override
    @Transactional
    public boolean updatePlaylist(Long playlistId, String playlistName, String description, String coverUrl, Boolean isPublic) {
        try {
            Playlist playlist = new Playlist();
            playlist.setPlaylistId(playlistId);
            if (playlistName != null) {
                playlist.setPlaylistName(playlistName);
            }
            if (description != null) {
                playlist.setDescription(description);
            }
            if (coverUrl != null) {
                playlist.setCoverUrl(coverUrl);
            }
            if (isPublic != null) {
                playlist.setIsPublic(isPublic);
            }
            playlist.setUpdateTime(new Date());

            return playlistMapper.updateById(playlist) > 0;
        } catch (Exception e) {
            log.error("更新播放列表失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean deletePlaylist(Long playlistId, Long userId) {
        try {
            // 验证权限
            Playlist playlist = playlistMapper.selectById(playlistId);
            if (playlist == null || !playlist.getUserId().equals(userId)) {
                return false;
            }

            // 删除��放列表中的歌曲
            playlistSongMapper.delete(new QueryWrapper<PlaylistSong>().eq("playlist_id", playlistId));

            // 删除播放列表
            return playlistMapper.deleteById(playlistId) > 0;
        } catch (Exception e) {
            log.error("删除播放列表失败", e);
            return false;
        }
    }

    @Override
    public PageResult<Playlist> getUserPlaylists(Long userId, int page, int size) {
        Page<Playlist> pageRequest = new Page<>(page, size);
        QueryWrapper<Playlist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).orderByDesc("create_time");

        Page<Playlist> pageResult = playlistMapper.selectPage(pageRequest, queryWrapper);
        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal(),
                               pageResult.getSize(), pageResult.getCurrent());
    }

    @Override
    @Transactional
    public boolean addSongToPlaylist(Long playlistId, Long songId) {
        try {
            // 检查歌曲是否已存在
            QueryWrapper<PlaylistSong> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("playlist_id", playlistId).eq("song_id", songId);
            PlaylistSong existing = playlistSongMapper.selectOne(queryWrapper);

            if (existing != null) {
                return false; // 歌曲已存在
            }

            // 获取当前最大排序号
            QueryWrapper<PlaylistSong> maxOrderQuery = new QueryWrapper<>();
            maxOrderQuery.eq("playlist_id", playlistId).orderByDesc("sort_order").last("LIMIT 1");
            PlaylistSong maxOrderSong = playlistSongMapper.selectOne(maxOrderQuery);
            int nextOrder = maxOrderSong != null ? maxOrderSong.getSortOrder() + 1 : 1;

            // 添加歌曲到播放列表
            PlaylistSong playlistSong = new PlaylistSong();
            playlistSong.setPlaylistId(playlistId);
            playlistSong.setSongId(songId);
            playlistSong.setSortOrder(nextOrder);
            playlistSong.setAddTime(new Date());

            int result = playlistSongMapper.insert(playlistSong);

            if (result > 0) {
                // 更新播放列表歌曲数量
                updatePlaylistSongCount(playlistId);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("添加歌曲到播放列表失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean removeSongFromPlaylist(Long playlistId, Long songId) {
        try {
            QueryWrapper<PlaylistSong> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("playlist_id", playlistId).eq("song_id", songId);

            int result = playlistSongMapper.delete(queryWrapper);

            if (result > 0) {
                // 更新播放列表歌曲数量
                updatePlaylistSongCount(playlistId);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("从播放列表移除歌曲失败", e);
            return false;
        }
    }

    @Override
    public List<Long> getPlaylistSongs(Long playlistId) {
        QueryWrapper<PlaylistSong> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("playlist_id", playlistId).orderByAsc("sort_order");

        List<PlaylistSong> playlistSongs = playlistSongMapper.selectList(queryWrapper);
        return playlistSongs.stream()
                .map(PlaylistSong::getSongId)
                .collect(Collectors.toList());
    }

    @Override
    public PlaylistBasicInfo getPlaylistBasicInfo(Long playlistId) {
        Playlist playlist = playlistMapper.selectById(playlistId);
        if (playlist == null) {
            return null;
        }

        PlaylistBasicInfo info = new PlaylistBasicInfo();
        info.setPlaylistId(playlist.getPlaylistId());
        info.setPlaylistName(playlist.getPlaylistName());
        info.setUserId(playlist.getUserId());
        info.setDescription(playlist.getDescription());
        info.setCoverUrl(playlist.getCoverUrl());
        info.setIsPublic(playlist.getIsPublic());
        info.setSongCount(playlist.getSongCount());
        info.setPlayCount(playlist.getPlayCount());
        info.setCollectCount(playlist.getCollectCount());

        return info;
    }

    @Override
    public List<PlaylistBasicInfo> getPlaylistBasicInfoBatch(List<Long> playlistIds) {
        if (playlistIds == null || playlistIds.isEmpty()) {
            return Collections.emptyList();
        }

        List<Playlist> playlists = playlistMapper.selectBatchIds(playlistIds);
        return playlists.stream()
                .map(playlist -> {
                    PlaylistBasicInfo info = new PlaylistBasicInfo();
                    info.setPlaylistId(playlist.getPlaylistId());
                    info.setPlaylistName(playlist.getPlaylistName());
                    info.setUserId(playlist.getUserId());
                    info.setDescription(playlist.getDescription());
                    info.setCoverUrl(playlist.getCoverUrl());
                    info.setIsPublic(playlist.getIsPublic());
                    info.setSongCount(playlist.getSongCount());
                    info.setPlayCount(playlist.getPlayCount());
                    info.setCollectCount(playlist.getCollectCount());
                    return info;
                })
                .collect(Collectors.toList());
    }

    /**
     * 更新播放列表歌曲数量
     */
    private void updatePlaylistSongCount(Long playlistId) {
        QueryWrapper<PlaylistSong> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("playlist_id", playlistId);
        Long songCount = playlistSongMapper.selectCount(queryWrapper);

        Playlist playlist = new Playlist();
        playlist.setPlaylistId(playlistId);
        playlist.setSongCount(songCount.intValue());
        playlist.setUpdateTime(new Date());
        playlistMapper.updateById(playlist);
    }

    @Override
    public List<String> getAllPublicPlaylistTags() {
        try {
            QueryWrapper<Playlist> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("is_public", true)
                       .isNotNull("tags")
                       .ne("tags", "");

            List<Playlist> playlists = playlistMapper.selectList(queryWrapper);

            List<String> tags = playlists.stream()
                    .filter(playlist -> playlist.getTags() != null && !playlist.getTags().trim().isEmpty())
                    .flatMap(playlist -> {
                        String[] tagArray = playlist.getTags().split(",");
                        return java.util.Arrays.stream(tagArray)
                                .map(String::trim)
                                .filter(tag -> !tag.isEmpty());
                    })
                    .distinct()
                    .sorted()
                    .collect(Collectors.toList());

            // 在最前面添加"全部"选项
            List<String> result = new ArrayList<>();
            result.add("全部");
            result.addAll(tags);
            return result;
        } catch (Exception e) {
            log.error("获取公开播放列表标签失败", e);
            List<String> fallbackResult = new ArrayList<>();
            fallbackResult.add("全部");
            return fallbackResult;
        }
    }

    @Override
    public PageResult<Playlist> getPublicPlaylistsByTag(String tag, int page, int size) {
        try {
            Page<Playlist> pageRequest = new Page<>(page, size);
            QueryWrapper<Playlist> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("is_public", true);

            // 如果传入的是"全部"，则不添加标签过滤条件，获取所有公开播放列表
            if (!"全部".equals(tag)) {
                queryWrapper.like("tags", tag);
            }

            queryWrapper.orderByDesc("collect_count")
                       .orderByDesc("play_count")
                       .orderByDesc("create_time");

            Page<Playlist> pageResult = playlistMapper.selectPage(pageRequest, queryWrapper);
            return new PageResult<>(pageResult.getRecords(), pageResult.getTotal(),
                                   pageResult.getSize(), pageResult.getCurrent());
        } catch (Exception e) {
            log.error("根据标签获取公开播放列表失败", e);
            return new PageResult<>(Collections.emptyList(), 0L, (long) size, (long) page);
        }
    }

    @Override
    public List<SongBasicInfo> getPlaylistSongsWithDetails(Long playlistId) {
        try {
            // 获取播放列表中的歌曲ID列表
            List<Long> songIds = getPlaylistSongs(playlistId);

            if (songIds.isEmpty()) {
                return Collections.emptyList();
            }

            // 通过Feign客���端批量获取歌曲详细信息
            Result<List<SongBasicInfo>> result = musicServiceClient.getSongBasicInfoBatch(songIds);

            if (result != null && result.isSuccess() && result.getData() != null) {
                // 按照播放列表中的顺序重新排序
                List<SongBasicInfo> songDetails = result.getData();
                return songIds.stream()
                        .map(songId -> songDetails.stream()
                                .filter(song -> song.getSongId().equals(songId))
                                .findFirst()
                                .orElse(null))
                        .filter(song -> song != null)
                        .collect(Collectors.toList());
            } else {
                log.warn("获取歌曲详细信息失败，playlistId: {}, result: {}", playlistId, result);
                return Collections.emptyList();
            }
        } catch (Exception e) {
            log.error("获取播放列表歌曲详细信息失败，playlistId: {}", playlistId, e);
            return Collections.emptyList();
        }
    }

    @Override
    public PlaylistDetailDTO getPlaylistDetailWithUsername(Long playlistId) {
        try {
            Playlist playlist = playlistMapper.selectById(playlistId);
            if (playlist == null) {
                return null;
            }

            PlaylistDetailDTO dto = new PlaylistDetailDTO();
            dto.setPlaylistId(playlist.getPlaylistId());
            dto.setUserId(playlist.getUserId());
            dto.setPlaylistName(playlist.getPlaylistName());
            dto.setDescription(playlist.getDescription());
            dto.setCoverUrl(playlist.getCoverUrl());
            dto.setIsPublic(playlist.getIsPublic());
            dto.setSongCount(playlist.getSongCount());
            dto.setPlayCount(playlist.getPlayCount());
            dto.setCollectCount(playlist.getCollectCount());
            dto.setShareCount(playlist.getShareCount());
            dto.setTags(playlist.getTags());
            dto.setCreateTime(playlist.getCreateTime());
            dto.setUpdateTime(playlist.getUpdateTime());

            // 通过Feign客户端获取用户名
            try {
                Result<UserBasicInfo> userResult = userServiceClient.getUserBasicInfoInternal(playlist.getUserId());
                if (userResult != null && userResult.isSuccess() && userResult.getData() != null) {
                    dto.setUsername(userResult.getData().getUsername());
                } else {
                    dto.setUsername("未知用户");
                }
            } catch (Exception e) {
                log.warn("获取用户信息失败, userId: {}", playlist.getUserId(), e);
                dto.setUsername("未知用户");
            }

            return dto;
        } catch (Exception e) {
            log.error("获取播放列表详情失败, playlistId: {}", playlistId, e);
            return null;
        }
    }
}
